"""
安全相关功能
"""
import jwt
import logging
from fastapi import HTTPException, Depends, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from datetime import datetime, timedelta
from typing import Optional
from app.core.config import settings
from app.schemas.user import TokenData

# 获取日志记录器
logger = logging.getLogger(__name__)

security = HTTPBearer()

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """创建JWT访问令牌"""
    logger.info("创建JWT访问令牌")
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
    logger.debug(f"生成的JWT令牌: {encoded_jwt[:20]}...")
    return encoded_jwt

def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)) -> TokenData:
    """验证JWT令牌"""
    logger.info("验证JWT令牌")
    try:
        token = credentials.credentials

        logger.debug(f"接收到的令牌: {token[:20]}...")
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
        logger.debug(f"解码后的载荷: {payload}")
        username: str = payload.get("username")
        user_id: int = payload.get("user_id")
        if username is None:
            logger.warning("令牌中没有用户名(username)字段")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid authentication credentials",
            )
        if user_id is None:
            logger.warning("令牌中没有用户ID(user_id)字段")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid authentication credentials",
            )
        logger.info(f"用户认证成功: {username}")
        return TokenData(username=username, user_id=user_id)
    except jwt.ExpiredSignatureError:
        logger.warning("令牌已过期")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token has expired",
        )
    except jwt.PyJWTError as e:
        logger.error(f"令牌验证失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
        )